/**
 * Copyright (C) 2017 - 2020 https://github.com/joewee
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.bifrost.web.controller;

import com.alibaba.fastjson.JSON;
import com.bifrost.annotation.Authorization;
import com.bifrost.annotation.CurrentUser;
import com.bifrost.constant.BonusPointsSource;
import com.bifrost.constant.BonusPointsUpdatedDetail;
import com.bifrost.constant.CouponOrderPayType;
import com.bifrost.constant.OrderStatus;
import com.bifrost.constant.OrderType;
import com.bifrost.constant.RunningMode;
import com.bifrost.constant.SendCouponType;
import com.bifrost.entity.Coupon;
import com.bifrost.entity.Customer;
import com.bifrost.entity.MerchantStore;
import com.bifrost.entity.Order;
import com.bifrost.exception.BonusPointsNotEnoughException;
import com.bifrost.exception.CheckoutException;
import com.bifrost.exception.ProductUnavaliableException;
import com.bifrost.exception.PromotionException;
import com.bifrost.exception.UnsupportedShippingTypeException;
import com.bifrost.model.CouponModel;
import com.bifrost.model.CouponResponse;
import com.bifrost.model.ItemModel;
import com.bifrost.model.OrderModel;
import com.bifrost.common.model.ResultModel;
import com.bifrost.repository.CouponRepository;
import com.bifrost.service.*;
import com.bifrost.util.TransformUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Date;
import java.util.stream.Collectors;

/**
 * 提交订单结算相关控制器
 *
 * @author joewee
 * @version 1.0.0
 * @Date 2017/11/16 14:07
 */
@RestController
@Api("订单相关接口")
@RequestMapping("/api/order/")
public class CheckoutController {
    private static final Logger LOGGER = LoggerFactory.getLogger(CheckoutController.class);
    @Autowired
    OrderService orderService;
    @Autowired
    PricingService pricingService;
    @Autowired
    CheckoutService checkoutService;
    @Autowired
    StoreService storeService;
    @Autowired
    ShoppingCartService shoppingCartService;
    @Autowired
    OrderStatusHistoryService statusHistoryService;
    @Autowired
    CustomerService customerService;
    @Autowired
    CouponService couponService;
    @Autowired
    BonusPointsService bonusPointsService;

    @Value("${running.mode:#{null}}")
    private String runningMode;

    @Authorization
    @ApiOperation("保存/结算订单")
    @PostMapping("/checkout")
    public ResultModel saveOrder(@CurrentUser Long userId, String data) {
        LOGGER.info(data);
        OrderModel orderModel = JSON.parseObject(data, OrderModel.class);
        try {
            Customer user = customerService.findCustomer(userId);
            if (!Boolean.TRUE.equals(user.getMerchantStore().getAvailable())) {
                return ResultModel.error("门店未启用，不能提交订单");
            }
            if (orderService.isValidOrder(orderModel)) {
                Order order = orderService.newOrder(orderModel, user);
                MerchantStore store = orderService.allInOneStore(order);
                if (store == null) {
                    return ResultModel.error("订单中的商品属于不同店铺不能合并下单");
                }
                order.setMerchantStore(store);
                if (Boolean.TRUE.equals(order.isNeedService()) && !storeService.canService(order)) {
                    return ResultModel.error("所选门店不能提供订单所需的所有服务请更换其他门店");
                }
                order = orderService.getConfirmOrderData(order);
                //pricingService.executePricing(order);
                //orderService.save(order,true);
                checkoutService.performCheckout(order);
                //清空购物车
                Long cartId = orderModel.getCartId();
                if (cartId != null) {
                    shoppingCartService.deleteSkusByCart(user, store, cartId, orderModel.getItems().stream().map(ItemModel::getSkuId).collect(Collectors.toList()));
                }
                //0元购
                if (BigDecimal.ZERO.compareTo(order.getOrderTotal()) == 0) {
                    order.setOrderStatus(OrderStatus.CONFIRMED);
                    orderService.save(order);
                    statusHistoryService.writeHistory(order, "下单成功，系统已为您自动确认", Boolean.TRUE,null);
                    return ResultModel.ok();
                }
                /*
                if (RunningMode.DEVELOPMENT.equalsIgnoreCase(runningMode)) {
                    return ResultModel.ok().put("out_trade_no", order.getOutTradeNo())
                            .put("total_fee", 1)
                            .put("body", order.getDescription());
                } else {
                */
                    return ResultModel.ok().put("out_trade_no", order.getOutTradeNo())
                            .put("total_fee", order.getOrderTotal().multiply(BigDecimal.valueOf(100)))
                            .put("body", order.getDescription());
                //}
            } else {
                return ResultModel.error("保存订单失败,请检查订单信息");
            }
        } catch (CheckoutException e) {
            e.getCheckoutResponse();
            LOGGER.error(e.getMessage(), e);
        } catch (UnsupportedShippingTypeException e) {
            LOGGER.error(e.getMessage(), e);
        } catch (PromotionException e) {
            LOGGER.error(e.getMessage(), e);
        } catch (ProductUnavaliableException e){
            LOGGER.error(e.getErrorMsg(), e);
            return ResultModel.error("商品不可销售");
        }
        return ResultModel.error("保存订单失败");
    }

    @Authorization
    @ApiOperation("重新支付订单")
    @PostMapping("/rePay")
    public ResultModel rePay(@CurrentUser Long userId, @RequestParam Long orderId) {
        Order order = orderService.findOrderById(orderId);
        Customer user = customerService.findCustomer(userId);
        Customer customer = order.getCustomer();
        if (customer!=null&&user!=null&&customer.getCustomerId().equals(user.getCustomerId())) {
            //若更新外部交易号有可能导致重复交易
            //orderService.updateOutTradeNo(order);
           Date purchasedDate = order.getDatePurchased();
           if(purchasedDate.getTime()+30*60*1000<=System.currentTimeMillis()){
               return ResultModel.error("订单超过30分钟未付款已失效");
           }
            if (RunningMode.DEVELOPMENT.equalsIgnoreCase(runningMode)) {
                return ResultModel.ok().put("out_trade_no", order.getOutTradeNo())
                        .put("total_fee", 1)
                        .put("body", order.getDescription());
            } else {
                return ResultModel.ok().put("out_trade_no", order.getOutTradeNo())
                        .put("total_fee", order.getOrderTotal().multiply(BigDecimal.valueOf(100)))
                        .put("body", order.getDescription());
            }
        } else {
            return ResultModel.error("支付失败");
        }
    }


    @Authorization
    @ApiOperation("保存/结算优惠券订单")
    @PostMapping("/coupon/checkout")
    public ResultModel saveCouponOrder(@CurrentUser Long userId, Long couponId,Integer quantity,String payType) {
        Customer user = customerService.findCustomer(userId);
        if (!Boolean.TRUE.equals(user.getMerchantStore().getAvailable())) {
            return ResultModel.error("门店未启用，不能提交订单");
        }
        Coupon coupon = couponService.findCoupon(couponId);
        Order couponOrder = null;
        try {
            //积分兑换走原有领取优惠券接口
            if(CouponOrderPayType.BONUS_POINTS.name().equalsIgnoreCase(payType)){
                CouponResponse response = couponService.getCoupon(user,coupon.getCouponId(),SendCouponType.BASIC);
                if(response!=null&&response.isSuccess()){
                    CouponModel couponModel = TransformUtils.transformToCouponModel(response.getCouponDetail());
                    return ResultModel.ok("成功").put("coupon",couponModel);
                }else{
                    return ResultModel.error(response.getFailureReason());
                }
            }
        } catch (BonusPointsNotEnoughException e) {
            LOGGER.error("订单创建失败：",e.getErrorMsg());
            return ResultModel.error("优惠券购买失败");
        }
        //现金购买
        if(CouponOrderPayType.CASH.name().equalsIgnoreCase(payType)){
            couponOrder = orderService.newCouponOrder(coupon,quantity,user,payType);
            try {
                checkoutService.performCheckout(couponOrder);
            } catch (CheckoutException e) {
                e.printStackTrace();
                LOGGER.error(e.getMessage(), e);
            }
        }
        /*
        if(OrderType.BONUS_POINTS_BY_COUPON.equalsIgnoreCase(couponOrder.getOrderType())){
            return ResultModel.ok("积分兑换优惠券成功");
        }
        if (RunningMode.DEVELOPMENT.equalsIgnoreCase(runningMode)) {
            return ResultModel.ok().put("out_trade_no", couponOrder.getOutTradeNo())
                    .put("total_fee", 1)
                    .put("body", couponOrder.getDescription());
        } else {
        */
            return ResultModel.ok().put("out_trade_no", couponOrder.getOutTradeNo())
                    .put("total_fee", couponOrder.getOrderTotal().multiply(BigDecimal.valueOf(100)))
                    .put("body", couponOrder.getDescription());
        //}
    }
}
